home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / elm / elm2.3pl11 / src / elm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-18  |  22.5 KB  |  842 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: elm.c,v 4.1.1.1 90/12/19 09:44:06 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1.1.1 $   $State: Exp $
  6.  *
  7.  * This file and all associated files and documentation:
  8.  *             Copyright (c) 1986, 1987 Dave Taylor
  9.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  10.  *******************************************************************************
  11.  * Bug reports, patches, comments, suggestions should be sent to:
  12.  *
  13.  *    Syd Weinstein, Elm Coordinator
  14.  *    elm@DSI.COM            dsinc!elm
  15.  *
  16.  *******************************************************************************
  17.  * $Log:    elm.c,v $
  18.  * Revision 4.1.1.1  90/12/19  09:44:06  syd
  19.  * Fix not checking for mail before scanning
  20.  * From: Syd via report from Joern Lubkoll
  21.  * 
  22.  * Revision 4.1  90/04/28  22:42:54  syd
  23.  * checkin of Elm 2.3 as of Release PL0
  24.  * 
  25.  *
  26.  ******************************************************************************/
  27.  
  28. /* Main program of the ELM mail system! 
  29. */
  30.  
  31. #include "elm.h"
  32.  
  33. #ifdef BSD
  34. #undef        toupper
  35. #undef        tolower
  36. #endif
  37.  
  38. long bytes();
  39. char *format_long(), *parse_arguments();
  40.  
  41. main(argc, argv)
  42. int argc;
  43. char *argv[];
  44.     {
  45.     int  ch;
  46.     char address[SLEN], to_whom[SLEN], *req_mfile;
  47.     int  key_offset;        /** Position offset within keyboard string   **/
  48.     int  redraw,         /** do we need to rewrite the entire screen? **/
  49.          nucurr,         /** change message list or just the current message pointer...   **/
  50.          nufoot;         /** clear lines 16 thru bottom and new menu  **/
  51.     int  i,j;              /** Random counting variables (etc)          **/
  52.     int  pageon,         /** for when we receive new mail...          **/
  53.          last_in_folder;    /** for when we receive new mail too...      **/
  54.     long num;        /** another variable for fun..               **/
  55.     extern char version_buff[];
  56.     extern int errno;
  57.  
  58.     req_mfile = parse_arguments(argc, argv, to_whom);
  59.  
  60.     initialize(req_mfile);
  61.  
  62.     if (mail_only) {
  63.        dprint(3, (debugfile, "Mail-only: mailing to\n-> \"%s\"\n", 
  64.            format_long(to_whom, 3)));
  65.        if(!batch_only) {
  66.          sprintf(address, "Send only mode [ELM %s]", version_buff);
  67.          Centerline(1, address);
  68.        }
  69.        (void) sendmsg(to_whom, "", batch_subject, TRUE,
  70.          (batch_only ? NO : allow_forms), FALSE); 
  71.        leave(0);
  72.     } else if (check_only) {
  73.        do_check_only(to_whom);
  74.        leave(0);
  75.     }
  76.  
  77.     ScreenSize(&LINES, &COLUMNS);
  78.  
  79.     showscreen();
  80.  
  81.     while (1) {
  82.       redraw = 0;
  83.       nufoot = 0;
  84.       nucurr = 0;
  85.       if ((num = bytes(cur_folder)) != mailfile_size) {
  86.         dprint(2, (debugfile, "Just received %d bytes more mail (elm)\n", 
  87.             num - mailfile_size));
  88.         error("New mail has arrived! Hang on...");
  89.         fflush(stdin);    /* just to be sure... */
  90.         last_in_folder = message_count;
  91.         pageon = header_page;
  92.  
  93.         if ((errno = can_access(cur_folder, READ_ACCESS)) != 0) {
  94.           dprint(1, (debugfile,
  95.             "Error: given file %s as folder - unreadable (%s)!\n", 
  96.             cur_folder, error_name(errno)));
  97.           fprintf(stderr,"Can't open folder '%s' for reading!\n", cur_folder);
  98.           leave();
  99.           }
  100.  
  101.         newmbox(cur_folder, TRUE);    /* last won't be touched! */
  102.         clear_error();
  103.         header_page = pageon;
  104.  
  105.         if (on_page(current))   /* do we REALLY have to rewrite? */
  106.           showscreen();
  107.         else {
  108.           update_title();
  109.           ClearLine(LINES-1);         /* remove reading message... */
  110.           error2("%d new message%s received.", 
  111.              message_count - last_in_folder,
  112.              plural(message_count - last_in_folder));
  113.         }
  114.         /* mailfile_size = num; */
  115.         if (cursor_control)
  116.           transmit_functions(ON);    /* insurance */
  117.       }
  118.  
  119.       prompt("Command: ");
  120.  
  121.       CleartoEOLN();
  122.       ch = GetPrompt();
  123.       CleartoEOS();
  124. #ifdef DEBUG
  125.       if (! movement_command(ch))
  126.         dprint(4, (debugfile, "\nCommand: %c [%d]\n\n", ch, ch));
  127. #endif
  128.  
  129.       set_error("");    /* clear error buffer */
  130.  
  131.       MoveCursor(LINES-3,strlen("Command: "));
  132.  
  133.       switch (ch) {
  134.  
  135.         case '?'     :  if (help(FALSE))
  136.                    redraw++;
  137.                else
  138.                  nufoot++;
  139.                break;
  140.  
  141.         case '$'    :  PutLine0(LINES-3, strlen("Command: "),
  142.                      "Resynchronize folder");
  143.                redraw = resync();
  144.                break;
  145.  
  146. next_page:
  147.         case '+'    :  /* move to next page if we're not on the last */
  148.                if((selected &&
  149.                  ((header_page+1)*headers_per_page < selected))
  150.                ||(!selected &&
  151.                  ((header_page+1)*headers_per_page<message_count))){
  152.  
  153.                  header_page++;
  154.                  nucurr = NEW_PAGE;
  155.  
  156.                  if(move_when_paged) {
  157.                    /* move to first message of new page */
  158.                    if(selected)
  159.                  current = visible_to_index(
  160.                    header_page * headers_per_page + 1) + 1;
  161.                    else
  162.                  current = header_page * headers_per_page + 1;
  163.                  }
  164.                } else error("Already on last page.");
  165.                break;
  166.  
  167. prev_page:
  168.         case '-'    :  /* move to prev page if we're not on the first */
  169.                if(header_page > 0) {
  170.                  header_page--;
  171.                  nucurr = NEW_PAGE;
  172.  
  173.                  if(move_when_paged) {
  174.                    /* move to first message of new page */
  175.                    if(selected)
  176.                  current = visible_to_index(
  177.                    header_page * headers_per_page + 1) + 1;
  178.                    else
  179.                  current = header_page * headers_per_page + 1;
  180.                  }
  181.                } else error("Already on first page.");
  182.                break;
  183.  
  184. first_msg:
  185.         case '='    :  if (selected)
  186.                  current = visible_to_index(1)+1;
  187.                else
  188.                  current = 1;
  189.                nucurr = get_page(current);
  190.                break;
  191.  
  192. last_msg:
  193.         case '*'    :  if (selected) 
  194.                  current = (visible_to_index(selected)+1);
  195.                else
  196.                  current = message_count;    
  197.                nucurr = get_page(current);
  198.                break;
  199.  
  200.         case '|'    :  Writechar('|'); 
  201.                if (message_count < 1) {
  202.                  error("No mail to pipe!");
  203.                  fflush(stdin);
  204.                } else {
  205.                      softkeys_off();
  206.                              redraw = do_pipe();        
  207.                  softkeys_on();
  208.                }
  209.                break;
  210.  
  211. #ifdef ALLOW_SUBSHELL
  212.         case '!'    :  Writechar('!'); 
  213.                            redraw = subshell();        
  214.                break;
  215. #endif
  216.  
  217.         case '%'    :  if (current > 0) {
  218.                  get_return(address, current-1);
  219.                  clear_error();
  220.                  PutLine1(LINES,(COLUMNS-strlen(address))/2,
  221.                       "%.78s", address);    
  222.                } else {
  223.                  error("No mail to get return address of!"); 
  224.                  fflush(stdin);
  225.                }
  226.                break;
  227.  
  228.         case '/'    :  /* scan mbox for string */
  229.                if  (message_count < 1) {
  230.                  error("No mail to scan!");
  231.                  fflush(stdin);
  232.                }
  233.                else if (pattern_match())
  234.                  nucurr = get_page(current);
  235.                else {
  236.                  error("pattern not found!");
  237.                  fflush(stdin);
  238.                }
  239.                break;
  240.  
  241.         case '<'    :  /* scan current message for calendar information */
  242. #ifdef ENABLE_CALENDAR
  243.                if  (message_count < 1) {
  244.                  error("No mail to scan!");
  245.                  fflush(stdin);
  246.                }
  247.                else {
  248.                    PutLine0(LINES-3, strlen("Command: "),     
  249.                    "Scan message for calendar entries...");
  250.                    scan_calendar();
  251.                }
  252. #else
  253.                 error("Sorry. Calendar function disabled.");
  254.                fflush(stdin);
  255. #endif
  256.                break;
  257.  
  258.         case 'a'    :  if(alias()) redraw++;
  259.                else nufoot++;     
  260.                define_softkeys(MAIN);     break;
  261.             
  262.         case 'b'    :  PutLine0(LINES-3, strlen("Command: "), 
  263.                  "Bounce message");
  264.                fflush(stdout);
  265.                if (message_count < 1) {
  266.                    error("No mail to bounce!");
  267.                  fflush(stdin);
  268.                }
  269.                else 
  270.                  nufoot = remail();
  271.                break;
  272.  
  273.         case 'c'    :  PutLine0(LINES-3, strlen("Command: "), 
  274.                   "Change folder");
  275.                define_softkeys(CHANGE);
  276.                redraw = change_file();
  277.                define_softkeys(MAIN);
  278.                break;
  279.  
  280.         case ctrl('D') :
  281.         case '^'    :
  282.         case 'd'    :  if (message_count < 1) {
  283.                  error("No mail to delete!");
  284.                  fflush(stdin);
  285.                }
  286.                else {
  287.                  if(ch == ctrl('D')) {
  288.  
  289.                    /* if current message did not become deleted,
  290.                 * don't to move to the next undeleted msg. */
  291.                    if(!meta_match(DELETED)) break;
  292.  
  293.                  } else 
  294.                     delete_msg((ch == 'd'), TRUE);
  295.  
  296.                  if (resolve_mode)     /* move after mail resolved */
  297.                    if((i=next_message(current-1, TRUE)) != -1) {
  298.                  current = i+1;
  299.                  nucurr = get_page(current);
  300.                    }
  301.                }
  302.                break;
  303.  
  304.  
  305. #ifdef ALLOW_MAILBOX_EDITING
  306.         case 'e'    :  PutLine0(LINES-3,strlen("Command: "),"Edit folder");
  307.                if (current > 0) {
  308.                  edit_mailbox();
  309.                      if (cursor_control)
  310.                    transmit_functions(ON);    /* insurance */
  311.                   }
  312.                else {
  313.                  error("Folder is empty!");
  314.                  fflush(stdin);
  315.                }
  316.                break;
  317. #else
  318.         case 'e'    : error(
  319.             "Folder editing isn't configured in this version of ELM.");
  320.               fflush(stdin);
  321.               break;
  322. #endif
  323.         
  324.         case 'f'    :  PutLine0(LINES-3, strlen("Command: "), "Forward");
  325.                define_softkeys(YESNO);
  326.                if (current > 0) {
  327.                  if(forward()) redraw++;
  328.                  else nufoot++;
  329.                } else {
  330.                  error("No mail to forward!");
  331.                  fflush(stdin);
  332.                }
  333.                define_softkeys(MAIN);
  334.                break;
  335.  
  336.         case 'g'    :  PutLine0(LINES-3,strlen("Command: "), "Group reply");
  337.                fflush(stdout);
  338.                if (current > 0) {
  339.                  if (headers[current-1]->status & FORM_LETTER) {
  340.                    error("Can't group reply to a Form!!");
  341.                    fflush(stdin);
  342.                  }
  343.                  else {
  344.                    define_softkeys(YESNO);
  345.                    redraw = reply_to_everyone();    
  346.                    define_softkeys(MAIN);
  347.                  }
  348.                }
  349.                else {
  350.                  error("No mail to reply to!"); 
  351.                  fflush(stdin);
  352.                }
  353.                break;
  354.  
  355.         case 'h'    :  if (filter)
  356.                  PutLine0(LINES-3, strlen("Command: "), 
  357.                 "Message with headers...");
  358.                else
  359.                  PutLine0(LINES-3, strlen("Command: "),"Display message");
  360.                if(current > 0) {
  361.                  fflush(stdout);
  362.                  j = filter;
  363.                  filter = FALSE;
  364.                  i = show_msg(current);
  365.                  while (i)
  366.                 i = process_showmsg_cmd(i);
  367.                  filter = j;
  368.                  redraw++;
  369.                  (void)get_page(current);
  370.                } else error("No mail to read!");
  371.                break;
  372.  
  373.         case 'J'    :  if(current > 0) {
  374.                  if((i=next_message(current-1, FALSE)) != -1) {
  375.                    current = i+1;
  376.                    nucurr = get_page(current);
  377.                  } else error("No more messages below.");
  378.                } else error("No mail in folder!");
  379.                break;
  380.  
  381. next_undel_msg:
  382.         case 'j'    :  if(current > 0) {
  383.                  if((i=next_message(current-1, TRUE)) != -1) {
  384.                    current = i+1;
  385.                    nucurr = get_page(current);
  386.                  } else error("No more undeleted messages below.");
  387.                } else error("No mail in folder!");
  388.                break;
  389.  
  390.         case 'K'    :  if(current > 0) {
  391.                  if((i=prev_message(current-1, FALSE)) != -1) {
  392.                    current = i+1;
  393.                    nucurr = get_page(current);
  394.                  } else error("No more messages above.");
  395.                } else error("No mail in folder!");
  396.                break;
  397.  
  398. prev_undel_msg:
  399.         case 'k'    :  if(current > 0) {
  400.                  if((i=prev_message(current-1, TRUE)) != -1) {
  401.                    current = i+1;
  402.                    nucurr = get_page(current);
  403.                  } else error("No more undeleted messages above.");
  404.                } else error("No mail in folder!");
  405.                break;
  406.  
  407.         case 'l'    :  PutLine0(LINES-3, strlen("Command: "),
  408.                    "Limit displayed messages by...");
  409.                clear_error();
  410.                if (limit() != 0) {
  411.                  get_page(current);
  412.                  redraw++;
  413.                } else {
  414.                  nufoot++;
  415.                }
  416.                break;
  417.  
  418.         case 'm'    :  PutLine0(LINES-3, strlen("Command: "), "Mail");
  419.                redraw = sendmsg("", "", "", TRUE,allow_forms,FALSE); 
  420.                break;
  421.  
  422.         case ' '    : 
  423.         case ctrl('J'):
  424.         case ctrl('M'):PutLine0(LINES-3, strlen("Command: "), 
  425.                       "Display message");    
  426.                fflush(stdout);
  427.                if(current > 0 ) {
  428.                  define_softkeys(READ);
  429.  
  430.                  i = show_msg(current);
  431.                  while (i)
  432.                 i = process_showmsg_cmd(i);
  433.                  redraw++;
  434.                  (void)get_page(current);
  435.                }else error ("No mail to read!");
  436.                break;
  437.  
  438.         case 'n'    :  PutLine0(LINES-3,strlen("Command: "),"Next Message");
  439.                fflush(stdout);
  440.                define_softkeys(READ);
  441.  
  442.                if(current > 0 ) {
  443.                  define_softkeys(READ);
  444.  
  445.                  i = show_msg(current);
  446.                  while (i)
  447.                    i = process_showmsg_cmd(i);
  448.                  redraw++;
  449.                  if (++current > message_count)
  450.                    current = message_count;
  451.                  (void)get_page(current);
  452.                }else error ("No mail to read!");
  453.                break;
  454.  
  455.         case 'o'    :  PutLine0(LINES-3, strlen("Command: "), "Options");
  456.                if((i=options()) > 0)
  457.                  get_page(current);
  458.                else if(i < 0)
  459.                  leave();
  460.                redraw++;    /* always fix da screen... */
  461.                break;
  462.  
  463.         case 'p'    :  PutLine0(LINES-3, strlen("Command: "), "Print mail");
  464.                fflush(stdout);
  465.                if (message_count < 1) {
  466.                  error("No mail to print!");
  467.                  fflush(stdin);
  468.                }
  469.                else
  470.                  print_msg();            
  471.                break;
  472.  
  473.         case 'q'    :  PutLine0(LINES-3, strlen("Command: "), "Quit");
  474.  
  475.                if (mailfile_size != bytes(cur_folder)) {
  476.                  error("New Mail!  Quit cancelled...");
  477.                  fflush(stdin);
  478.                    if (folder_type == SPOOL) unlock();
  479.                }
  480.                else
  481.                  quit(TRUE);        
  482.  
  483.                break;
  484.  
  485.         case 'Q'    :  PutLine0(LINES-3, strlen("Command: "), "Quick quit");
  486.  
  487.                if (mailfile_size != bytes(cur_folder)) {
  488.                  error("New Mail!  Quick Quit cancelled...");
  489.                    if (folder_type == SPOOL) unlock();
  490.                }
  491.                else
  492.                  quit(FALSE);        
  493.  
  494.                break;
  495.  
  496.         case 'r'    :  PutLine0(LINES-3, strlen("Command: "), 
  497.                   "Reply to message");
  498.                if (current > 0) 
  499.                  redraw = reply();    
  500.                else {
  501.                  error("No mail to reply to!"); 
  502.                  fflush(stdin);
  503.                }
  504.                softkeys_on();
  505.                break;
  506.  
  507.         case '>'    : /** backwards compatibility **/
  508.  
  509.         case 'C'    :
  510.         case 's'    :  if  (message_count < 1) {
  511.                  error1("No mail to %s!",
  512.                    ch != 'C' ? "save" : "copy");
  513.                  fflush(stdin);
  514.                }
  515.                else {
  516.                  PutLine1(LINES-3, strlen("Command: "),
  517.                       "%s to folder",
  518.                       ch != 'C' ? "Save" : "Copy");
  519.                  PutLine0(LINES-3,COLUMNS-40,
  520.                 "(Use '?' to list your folders)");
  521.                  if (save(&redraw, FALSE, (ch != 'C'))
  522.                  && resolve_mode && ch != 'C') {
  523.                    if((i=next_message(current-1, TRUE)) != -1) {
  524.                  current = i+1;
  525.                  nucurr = get_page(current);
  526.                    }
  527.                  }
  528.                }
  529.                ClearLine(LINES-2);        
  530.                break;
  531.  
  532.             case ctrl('T') :
  533.         case 't'       :  if (message_count < 1) {
  534.                 error("No mail to tag!");
  535.                 fflush(stdin);
  536.                   }
  537.                   else if (ch == 't')
  538.                 tag_message(TRUE); 
  539.                   else
  540.                 meta_match(TAGGED);
  541.                   break;
  542.  
  543.         case 'u'    :  if (message_count < 1) {
  544.                  error("No mail to mark as undeleted!");
  545.                  fflush(stdin);
  546.                }
  547.                else {
  548.                  undelete_msg(TRUE);
  549.                  if (resolve_mode)     /* move after mail resolved */
  550.                    if((i=next_message(current-1, FALSE)) != -1) {
  551.                  current = i+1;
  552.                  nucurr = get_page(current);
  553.                    }
  554. /*************************************************************************
  555.  **  What we've done here is to special case the "U)ndelete" command to
  556.  **  ignore whether the next message is marked for deletion or not.  The
  557.  **  reason is obvious upon usage - it's a real pain to undelete a series
  558.  **  of messages without this quirk.  Thanks to Jim Davis @ HPLabs for
  559.  **  suggesting this more intuitive behaviour.
  560.  **
  561.  **  The old way, for those people that might want to see what the previous
  562.  **  behaviour was to call next_message with TRUE, not FALSE.
  563. **************************************************************************/
  564.                }
  565.                break;
  566.  
  567.         case ctrl('U') : if (message_count < 1) {
  568.                    error("No mail to undelete!");
  569.                    fflush(stdin);
  570.                  }
  571.                  else 
  572.                    meta_match(UNDELETE);
  573.                  break;
  574.  
  575.         case 'X'    :  PutLine0(LINES-3, strlen("Command: "), "Quick Exit");
  576.                            fflush(stdout);
  577.                leave();
  578.                break;
  579.  
  580.         case ctrl('Q') :
  581.         case 'x'    :  PutLine0(LINES-3, strlen("Command: "), "Exit");  
  582.                            fflush(stdout);
  583.                exit_prog();
  584.                break;
  585.  
  586.         case ctrl('L') : redraw++;    break;
  587.  
  588.             case EOF :  leave();  /* Read failed, control tty died? */
  589.                         break;
  590.         
  591.         case '@'    : debug_screen();  redraw++;    break;
  592.     
  593.         case '#'    : if (message_count) {
  594.                 debug_message(); 
  595.                 redraw++;    
  596.               } 
  597.               else {
  598.                 error("No mail to check.");
  599.                 fflush(stdin);
  600.               }
  601.               break;
  602.  
  603.         case NO_OP_COMMAND : break;    /* noop for timeout loop */
  604.  
  605.         case ESCAPE : if (cursor_control) {
  606.                 key_offset = 1;
  607.                 ch = ReadCh(); 
  608.   
  609.                             if ( ch == '[' || ch == 'O')
  610.                             {
  611.                               ch = ReadCh();
  612.                               key_offset++;
  613.                             }
  614.   
  615.                 if(ch == up[key_offset]) goto prev_undel_msg;
  616.                 else if(ch == down[key_offset]) goto next_undel_msg;
  617.                 else if(ch == right[key_offset]) goto next_page;
  618.                 else if(ch == left[key_offset]) goto prev_page;
  619.                 else if (hp_terminal) {
  620.                   switch (ch) {
  621.                   case 'U':        goto next_page;
  622.                   case 'V':        goto prev_page;
  623.                   case 'h':     
  624.                   case 'H':        goto first_msg;
  625.                   case 'F':        goto last_msg;
  626.                   case 'A':
  627.                   case 'D':
  628.                   case 'i':        goto next_undel_msg;
  629.                   case 'B':
  630.                   case 'I':
  631.                   case 'C':        goto prev_undel_msg;
  632.                   default: PutLine2(LINES-3, strlen("Command: "), 
  633.                     "%c%c", ESCAPE, ch);
  634.                   }
  635.                 } else /* false hit - output */
  636.                   PutLine2(LINES-3, strlen("Command: "), 
  637.                       "%c%c", ESCAPE, ch);
  638.               }
  639.  
  640.               /* else fall into the default error message! */
  641.  
  642.         default    : if (ch > '0' && ch <= '9') {
  643.                 PutLine0(LINES-3, strlen("Command: "), 
  644.                     "New Current Message");
  645.                 i = read_number(ch);
  646.  
  647.                 if( i > message_count)
  648.                   error("Not that many messages.");
  649.                 else if(selected
  650.                 && isoff(headers[i-1]->status, VISIBLE))
  651.                   error("Message not in limited display.");
  652.                 else {
  653.                   current = i;
  654.                   nucurr = get_page(current);
  655.                 }
  656.               }
  657.               else {
  658.                  error("Unknown command. Use '?' for help.");
  659.                 fflush(stdin);
  660.               }
  661.       }
  662.  
  663.       if (redraw)
  664.         showscreen();
  665.  
  666.       if ((current < 1) || (selected && compute_visible(current) < 1)) {
  667.         if (message_count > 0) {
  668.           /* We are out of range! Get to first message! */
  669.           if (selected)
  670.         current = compute_visible(1);
  671.           else
  672.         current = 1;
  673.         }
  674.         else
  675.           current = 0;
  676.       }
  677.       else if ((current > message_count)
  678.            || (selected && compute_visible(current) > selected)) {
  679.         if (message_count > 0) {
  680.           /* We are out of range! Get to last (visible) message! */
  681.           if (selected)
  682.         current = visible_to_index(selected)+1;
  683.           else
  684.         current = message_count;
  685.         }
  686.         else
  687.           current = 0;
  688.       }
  689.         
  690.       if (nucurr == NEW_PAGE) 
  691.         show_headers();
  692.       else if (nucurr == SAME_PAGE)
  693.         show_current();
  694.       else if (nufoot) {
  695.         if (mini_menu) {
  696.           MoveCursor(LINES-7, 0);  
  697.               CleartoEOS();
  698.           show_menu();
  699.         }
  700.         else {
  701.           MoveCursor(LINES-4, 0);
  702.           CleartoEOS();
  703.         }
  704.         show_last_error();    /* for those operations that have to
  705.                  * clear the footer except for a message.
  706.                  */
  707.       }
  708.  
  709.     } /* the BIG while loop! */
  710. }
  711.  
  712. debug_screen()
  713. {
  714.     /**** spit out all the current variable settings and the table
  715.           entries for the current 'n' items displayed. ****/
  716.  
  717.     register int i, j;
  718.     char     buffer[SLEN];
  719.  
  720.     ClearScreen();
  721.     Raw(OFF);
  722.  
  723.     PutLine2(0,0,"Current message number = %d\t\t%d message(s) total\n",
  724.         current, message_count);
  725.     PutLine2(2,0,"Header_page = %d           \t\t%d possible page(s)\n",
  726.         header_page, (int) (message_count / headers_per_page) + 1);
  727.  
  728.     PutLine1(4,0,"\nCurrent mailfile is %s.\n\n", cur_folder);
  729.  
  730.     i = header_page*headers_per_page;    /* starting header */
  731.  
  732.     if ((j = i + (headers_per_page-1)) >= message_count) 
  733.       j = message_count-1;
  734.  
  735.     Write_to_screen(
  736. "Num      From                     Subject                         Lines  Offset\n\r\n\r",0);
  737.  
  738.     while (i <= j) {
  739.        sprintf(buffer, 
  740.        "%3d  %-16.16s  %-40.40s  %4d  %d\n\r",
  741.             i+1,
  742.             headers[i]->from, 
  743.             headers[i]->subject,
  744.             headers[i]->lines,
  745.             headers[i]->offset);
  746.         Write_to_screen(buffer, 0);
  747.       i++;
  748.     }
  749.     
  750.     Raw(ON);
  751.  
  752.     PutLine0(LINES,0,"Press any key to return.");
  753.     (void) ReadCh();
  754. }
  755.  
  756.  
  757. debug_message()
  758. {
  759.     /**** Spit out the current message record.  Include EVERYTHING
  760.           in the record structure. **/
  761.     
  762.     char buffer[SLEN];
  763.     register struct header_rec *current_header = headers[current-1];
  764.  
  765.     ClearScreen();
  766.     Raw(OFF);
  767.  
  768.     Write_to_screen("\t\t\t----- Message %d -----\n\r\n\r\n\r\n\r", 1,
  769.         current);
  770.  
  771.     Write_to_screen("Lines : %-5d\t\t\tStatus: A  C  D  E  F  N  O  P  T  U  V\n\r", 1,
  772.         current_header->lines);
  773.     Write_to_screen("            \t\t\t        c  o  e  x  o  e  l  r  a  r  i\n\r", 0);
  774.     Write_to_screen("            \t\t\t        t  n  l  p  r  w  d  i  g  g  s\n\r", 0);
  775.     Write_to_screen("            \t\t\t        n  f  d  d  m        v  d  n  i\n\r", 0);
  776.  
  777.     sprintf(buffer, 
  778.         "\n\rOffset: %ld\t\t\t        %d  %d  %d  %d  %d",
  779.         current_header->offset,
  780.         (current_header->status & ACTION) != 0,
  781.         (current_header->status & CONFIDENTIAL) != 0,
  782.         (current_header->status & DELETED) != 0,
  783.         (current_header->status & EXPIRED) != 0,
  784.         (current_header->status & FORM_LETTER) != 0);
  785.     sprintf(buffer + strlen(buffer),
  786.         "  %d  %d  %d  %d  %d  %d\n",
  787.         (current_header->status & NEW) != 0,
  788.         (current_header->status & UNREAD) != 0,
  789.         (current_header->status & PRIVATE) != 0,
  790.         (current_header->status & TAGGED) != 0,
  791.         (current_header->status & URGENT) != 0,
  792.         (current_header->status & VISIBLE) != 0);
  793.  
  794.     Write_to_screen(buffer, 0);
  795.  
  796.     sprintf(buffer, "\n\rReceived on: %d/%d/%d at %d:%02d\n\r",
  797.         current_header->received.month+1,
  798.         current_header->received.day,
  799.         current_header->received.year,
  800.         current_header->received.hour,
  801.         current_header->received.minute);
  802.     Write_to_screen(buffer, 0);
  803.  
  804.     sprintf(buffer, "Message sent on: %s, %s %s, %s at %s\n\r",
  805.         current_header->dayname,
  806.         current_header->month,
  807.         current_header->day,
  808.         current_header->year,
  809.         current_header->time);
  810.     Write_to_screen(buffer, 0);
  811.     
  812.     Write_to_screen("From: %s\n\rSubject: %s", 2,
  813.         current_header->from,
  814.         current_header->subject);
  815.  
  816.     Write_to_screen("\n\rPrimary Recipient: %s\nInternal Index Reference Number = %d\n\r", 2,
  817.         current_header->to,
  818.         current_header->index_number);
  819.  
  820.     Write_to_screen("Message-ID: %s\n\r", 1,
  821.         strlen(current_header->messageid) > 0 ? 
  822.         current_header->messageid : "<none>");
  823.  
  824.     Write_to_screen("Status: %s\n\r", 1, current_header->mailx_status);
  825.     
  826.     Raw(ON);
  827.  
  828.     PutLine0(LINES,0,"Please Press any key to return.");
  829.     (void) ReadCh();
  830. }
  831.  
  832. do_check_only(to_whom)
  833. char *to_whom;
  834.     {
  835.     char buffer[VERY_LONG_STRING];
  836.  
  837.     dprint(3, (debugfile, "Check-only: checking \n-> \"%s\"\n", 
  838.         format_long(to_whom, 3)));
  839.     (void) build_address(strip_commas(to_whom), buffer); 
  840.     printf("Expands to: %s", format_long(buffer, strlen("Expands to: ")));
  841.     }
  842.